/**
 *	\file AKCommon.h
 *  
 *  \section desc_sec Description
 *  Description
 *  
 *  \if copyright
 *  	Copyright 2008 Ben Chen. All rights reserved.
 *  \endif
 *  
 *  \section hist_sec Change History:
 *  	-	1/13/08		BC		Created this file
 *  
 *  <hr>
 *  \addtogroup AnimalKingdom
 * @{
 */

#pragma once

#ifndef _AKCOMMON_H_
#define _AKCOMMON_H_

#ifndef __OBJC__

typedef signed char		BOOL; 

#if !defined(YES)
#define YES	(BOOL)1
#endif

#if !defined(NO)
#define NO	(BOOL)0
#endif

/*
#include <limits.h>
enum {NSNotFound = LONG_MAX};
*/
enum {NSNotFound = 0x7fffffff};

#if defined(__WIN32__)
	#undef FOUNDATION_EXPORT
	#if defined(NSBUILDINGFOUNDATION)
	#define FOUNDATION_EXPORT __declspec(dllexport) extern
	#else
	#define FOUNDATION_EXPORT __declspec(dllimport) extern
	#endif
	#if !defined(FOUNDATION_IMPORT)
	#define FOUNDATION_IMPORT __declspec(dllimport) extern
	#endif
#endif

#if defined(__cplusplus)
	#define FOUNDATION_EXPORT extern "C"
	#define FOUNDATION_IMPORT extern "C"
#endif

#if !defined(FOUNDATION_EXPORT)
	#define FOUNDATION_EXPORT extern
#endif

#if !defined(FOUNDATION_IMPORT)
	#define FOUNDATION_IMPORT extern
#endif

#if !defined(NS_INLINE)
	#if defined(__GNUC__)
		#define NS_INLINE static __inline__ __attribute__((always_inline))
	#elif defined(__MWERKS__) || defined(__cplusplus)
		#define NS_INLINE static inline
	#elif defined(_MSC_VER)
		#define NS_INLINE static __inline
	#elif defined(__WIN32__)
		#define NS_INLINE static __inline__
	#endif
#endif

#if !defined(FOUNDATION_STATIC_INLINE)
#define FOUNDATION_STATIC_INLINE static __inline__
#endif

#if !defined(FOUNDATION_EXTERN_INLINE)
#define FOUNDATION_EXTERN_INLINE extern __inline__
#endif

#endif // __OBJC__

typedef unsigned int AKSideIndex;
typedef unsigned int AKPieceIndex;

typedef unsigned int AKCellIndex;

typedef unsigned int AKWalkDirection;
typedef unsigned int AKWalkType;

typedef struct _AKWalk
{
	AKWalkDirection	direction;
	AKWalkType		type;
} AKWalk;

typedef struct _AKPiece
{
	AKSideIndex		side;
	AKPieceIndex	piece;
	AKCellIndex		cell;
} AKPiece;

//typedef AKCell AKPiece;

typedef struct _AKMove 
{
	AKSideIndex		side;		///< The side of the piece.
	AKPieceIndex	piece;		///< The index of the piece.
	AKCellIndex		srcCell;	///< The cell where the piece is now. If the piece is new, then this value is NSNotFound.
	
	AKCellIndex		dstCell;	///< The cell which the piece is going to. If the piece is removed from the chessboard, then this value is NSNotFound.
} AKMove;

NS_INLINE BOOL AKEqualPieces(AKPiece aPiece, AKPiece bPiece)
{
	BOOL retVal = NO;
	
	if (aPiece.cell == bPiece.cell && aPiece.piece == bPiece.piece && aPiece.side == bPiece.side)
		retVal = YES;
	
	return retVal;
}

NS_INLINE AKPiece AKPieceInMove(AKMove aMove, BOOL useSrcCell)
{
	AKPiece newPiece;
	newPiece.side = aMove.side;
	newPiece.piece = aMove.piece;
	
	if (useSrcCell)
		newPiece.cell = aMove.srcCell;
	else
		newPiece.cell = aMove.dstCell;
	
	return newPiece;
}

#ifdef __OBJC__
NS_INLINE CGRect CGRectFromNSRect(NSRect rect)
{
	return CGRectMake(rect.origin.x, rect.origin.y, rect.size.width, rect.size.height);
}

NS_INLINE CGPoint CGPointFromNSPoint(NSPoint point)
{
	return CGPointMake(point.x, point.y);
}

NS_INLINE NSString* AKStringFromPiece(AKPiece piece)
{
	return [NSString stringWithFormat:@"s:%d i:%d c:%d", piece.side, piece.piece, piece.cell];
}

NS_INLINE NSString* AKStringFromMove(AKMove move)
{
	return [NSString stringWithFormat:@"p:%d s:%d src:%d dst:%d", move.piece, move.side, move.srcCell, move.dstCell];
}

#endif

FOUNDATION_EXPORT const AKPiece	AKZeroPiece;
FOUNDATION_EXPORT const AKMove	AKZeroMove;

#endif // _AKCOMMON_H_

/** @} */